/**
 * @addtogroup sfc_msg_queue.h
 * sfc_msg_queue.h
 * @{
 */
/**
 * @file sfc_msg_queue.h
 * @brief 消息队列 
 * @note 
 * @author Leo
 * @date 2020-11-20
 * @version 1.0

 * @par          修改日志
 * <table>
 * <tr><th>Date<th>Version<th>Author<th>Description
 * <tr><td>2020-11-20<td>1.0<td>Leo<td>创建初始版本
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _SFC_MSG_QUEUE_H_
#define _SFC_MSG_QUEUE_H_

#include <ofc_object.h>
#include "sfc_api.h"

#ifdef __cplusplus
extern "C" {
#endif

/// 定义宏,表示无限时长的等待
#define SF_WAIT_FOREVER 0xFFFFFFFF

/**
 * 构造消息队列类
 * @par 示例
 * @code 
   Thread A:
   TSfMsgQueue queue;
   TSfMsgQueueCreate(&queue, 10, 20);
   ...
   if (TSfMsgQueueGet(&queue, buf, NULL, 100)) ... // 从消息队列中获取一个消息,最多等待100ms

   Thread B:
   TSfMsgQueuePut(&queue, msg, 0, 100);  // 投递一个消息到消息队列

   OfDestroyObject((TOfObject *)&queue);
 * @endcode
*/
typedef struct TSfMsgQueueTag TSfMsgQueue;
struct TSfMsgQueueTag
{
PROTECTED
    TOfObject parent_;
    TOfVirtualMethod Destroy_;

PRIVATE
    TSfMsgQueueHandle handle_;
};

/**
 * 消息队列类的构造函数
 * @note 本函数不得在中断中调用;同样的,中断中不得析构本对象
 * @param self: 对象实例指针
 * @param msg_count: 队列中最大能保存的消息个数
 * @param msg_size: 消息的最大尺寸
 * @return 创建事件成功返回True,否则返回False
 */
Bool TSfMsgQueueCreate(TSfMsgQueue *self, UInt32 msg_count, UInt32 msg_size);

/**
 * 创建消息队列对象
 * @param msg_count: 队列中最大能保存的消息个数
 * @param msg_size: 消息的最大尺寸
 * @return 创建成功返回创建的对象,创建失败返回NULL
 */
TSfMsgQueue *SfCreateMsgQueue(UInt32 msg_count, UInt32 msg_size);

/**
 * 投递一个消息到消息队列.
 * @note 
 *   1. 在等待期间,调用线程会被阻塞
 *   2. 该函数可以在中断中调用
 * @param self: 对象实例指针
 * @param msg: 需要投递的消息的指针
 * @param priority: 定义消息的优先级(数字越大,优先级越高)
 * @param time_out: 投递数据到消息队列的等待时长,单位:毫秒.
 * - 超时值有3种情况
 * -# 0: 调用后立即返回
 * -# SF_WAIT_FOREVER: 等待直到消息成功投递
 * -# 其它值: 最多等待多少毫秒
 * @return 返回是否投递成功.True: 投递成功; False: 投递失败
 */
Bool TSfMsgQueuePut(TSfMsgQueue *self, const void *msg, UInt8 priority, UInt32 time_out);

/**
 * 从消息队列中取出一个消息.
 * @note 
 *   1. 在等待期间,调用线程会被阻塞
 *   2. 该函数可以在中断中调用
 * @param self: 对象实例指针
 * @param msg_buf: 用于存放消息的缓冲区
 * @param priority: 用于存放消息优先级的缓冲区(数字越大,优先级越高);可以为NULL
 * @param time_out: 投递数据到消息队列的等待时长,单位:毫秒.
 * - 超时值有3种情况
 * -# 0: 调用后立即返回
 * -# SF_WAIT_FOREVER: 等待直到消息成功投递
 * -# 其它值: 最多等待多少毫秒
 * @return 返回是否投递成功.True: 投递成功; False: 投递失败
 */
Bool TSfMsgQueueGet(TSfMsgQueue *self, void *msg_buf, UInt8 *priority, UInt32 time_out);

/**
 * 获取消息队列的容量(即可以存放的消息个数).
 * @note 
 *   该函数可以在中断中调用
 * @param self: 对象实例指针
 * @return 返回消息队列可以存放的消息个数
 */
UInt32 TSfMsgQueueGetCapacity(TSfMsgQueue *self);

/**
 * 获取单个消息的最大尺寸,单位:字节
 * @note 
 *   该函数可以在中断中调用
 * @param self: 对象实例指针
 * @return 返回消息的最大尺寸
 */
UInt32 TSfMsgQueueGetMsgSize(TSfMsgQueue *self);

/**
 * 获取消息队列中消息的个数
 * @note 
 *    该函数可以在中断中调用
 * @param self: 对象实例指针
 * @return 返回消息的个数
 */
UInt32 TSfMsgQueueGetCount(TSfMsgQueue *self);

/**
 * 获取消息队列中还可以存放的消息个数
 * @note 
 *    该函数可以在中断中调用
 * @param self: 对象实例指针
 * @return 返回还可以存放的消息个数
 */
UInt32 TSfMsgQueueGetFreeCount(TSfMsgQueue *self);

/**
 * 复位消息队列
 * @note 
 *   该函数不可以在中断中调用
 * @param self: 对象实例指针
 * @return 返回调用是否成功;True: 复位成功; False: 复位失败
 */
Bool TSfMsgQueueReset(TSfMsgQueue *self);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif // _SFC_MSG_QUEUE_H_

/**
 * @}
 */
